package com.bjtech.web.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.bjtech.dao.AssignDataFileDao;
import com.bjtech.dao.AssignMeterDataDao;
import com.bjtech.dao.UtilDao;
import com.bjtech.domain.AssignDataFile;
import com.bjtech.domain.AssignMeterData;
import com.bjtech.domain.query.AssignDataFileQuerySpec;

public class ReadAssignMeterData {
	//配置表文件的存储目录
	private String fileDir;
	
	//日志文件存储目录
	private String logfileDir;
	
	//读取后的文件的存放目录
	private String successFileDir;
	private String failFielDir;
	
	private AssignMeterDataDao assignMeterDataDao;
	private AssignDataFileDao assignDataFileDao;
	
	public ReadAssignMeterData(){
		initCfgFile();
		
//		assignMeterDataDao = (AssignMeterDataDao) InitServletContextListener.getBean("assignMeterDataDao");
//		assignDataFileDao = (AssignDataFileDao) InitServletContextListener.getBean("assignDataFileDao");
	}
	
	public void readData(){
		if(this.assignMeterDataDao==null){
			assignMeterDataDao = (AssignMeterDataDao) InitServletContextListener.getBean("assignMeterDataDao");
		}
		if(this.assignDataFileDao==null){
			assignDataFileDao = (AssignDataFileDao) InitServletContextListener.getBean("assignDataFileDao");
		}
		UtilDao utilDao=(UtilDao) InitServletContextListener.getBean("utilDao");
		int readCount = utilDao.updateSelectReadCount();
		utilDao.updateCount();
		if(readCount<150){
			List list = this.assignMeterDataDao.selectEntityList(new AssignMeterData(), new AssignDataFileQuerySpec());//file_id为0表示用GPRS上传的文件
			//读取meterFileDir目录下的文件列表
			String[] meterFiles = findFileList(fileDir);
			
			for(String meterFile:meterFiles){
				File mf = new File(fileDir+File.separatorChar+meterFile);
				//读取文件中的数据，并入库
				try {
					readFileDataNew(meterFile);
				} catch (IOException e) {
					File failFile = new File(failFielDir+File.separatorChar+mf.getName());
					try {
						removeFile(mf,failFile);
					} catch (IOException e1) {
						e1.printStackTrace();
					}
					e.printStackTrace();
				}
			}
		}
	}
	
	private void readFileDataNew(String meterFileName) throws IOException{
		//读取文件信息
		File meterFile = new File(fileDir+File.separatorChar+meterFileName);
		List<String> meterRecords = new ArrayList<String>();
		int record_num=0;
		int success_num=0;
		boolean success = true;
		
		BufferedReader br = null;
		FileReader fr = new FileReader(meterFile);
		try {
			br = new BufferedReader(fr);
			String meterRecord="";
			while((meterRecord=br.readLine())!=null){
				if(StringUtils.isNotBlank(meterRecord)&&StringUtils.isNotEmpty(meterRecord)){
					if(meterRecord.split(",").length==16) record_num++;
					if(record_num>10){//从第11条记录开始读取数据
						meterRecords.add(meterRecord);
					}
				}
			}
		} catch (Exception e) {
			success = false;
			e.printStackTrace();
		} finally{
			fr.close();
		}
		try{
			success_num = this.assignMeterDataDao.insertMeterDatas(meterRecords,0l);//file_id为0表示用GPRS上传的文件
		}catch(Exception e){
			File failFile = new File(failFielDir+File.separatorChar+meterFile.getName());
			File logFile = new File(failFielDir+File.separatorChar+meterFile.getName().substring(0,meterFile.getName().indexOf(".txt"))+"_log.log"); 
			PrintWriter writer = new PrintWriter(logFile);
			e.printStackTrace(writer);
			writer.close();
			try {
				removeFile(meterFile,failFile);
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			success = false;
		}
		
		//编写日志文件
		if(success){
			String log_info = "读取了文件["+meterFileName+"],读取了数据 "+record_num+"条，成功读取"+success_num+"条";
			File logFile = new File(successFileDir+File.separatorChar+meterFile.getName().substring(0,meterFile.getName().indexOf(".txt"))+"_log.log"); 
			FileWriter writer = new FileWriter(logFile);
			writer.write(log_info);
			writer.close();
			//将读取过的文件放在
			File successFile = new File(successFileDir+File.separatorChar+meterFile.getName());
			removeFile(meterFile,successFile);
		}
	}

	private void removeFile(File srcFile, File destFile) throws IOException {
		FileInputStream  in  = new FileInputStream(srcFile);
		FileOutputStream out = new FileOutputStream(destFile);
		for (int c = in.read(); c != -1; c = in.read( )) {
		  out.write(c);
		}
		in.close( );
		out.close( );
		//删除原文件
		srcFile.delete();
	}

	private String[] findFileList(String fileDir2) {
		String[] fileNames = new File(fileDir).list(new FilenameFilter(){

			public boolean accept(File dir, String name) {
				if(name.endsWith("_G.txt")) return true;
				return false;
			}
			
		});
		return fileNames;
	}

	/**
	 * 将过程信息写入日志文件
	 * @param readEvent
	 */
	private void writeEventToLogFile(String readEvent) {
		String read;
		StringBuffer readStrBuf=new StringBuffer("");
		try {
			File logFile = createLogFile(logfileDir);
			FileReader fr = new FileReader(logFile);
			BufferedReader br = new BufferedReader(fr);
			while((read=br.readLine())!=null){
				readStrBuf.append(read).append("/r/n");
			}
			
			RandomAccessFile rf = new RandomAccessFile(logFile,"rw");
			rf.writeBytes(readStrBuf.toString()+readEvent+"/r/n");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获得日志文件
	 * 	如果存在就返回
	 *  否则创建一个新的文件
	 * @param fileDir
	 * @return
	 * @throws IOException 
	 */
	private File createLogFile(String fileDir) throws IOException {
		Calendar c = Calendar.getInstance();
		String file_name = fileDir+File.separator+c.get(Calendar.YEAR)+"-"+c.get(Calendar.MONTH)+".log";
		File logFile = new File(file_name);
		if(!logFile.exists()){
			logFile.createNewFile();
			logFile=new File(file_name);
		}
		return logFile;
	}

	/**
	 * 读取文件中的分配表数据，并入库
	 * 将文件信息同时入库
	 * @param meterFile
	 * @return
	 */
	private String readFileData(String meterFileName) {
		File meterFile = new File(meterFileName);
		AssignMeterData meterData = new AssignMeterData();
		AssignDataFile dataFile = new AssignDataFile(meterFile.getName(),new Date(),((float)meterFile.length())/1024);
		long record_num=0;
		long success_num=0;
		
		Long file_id = assignDataFileDao.insertEntity(dataFile);
		dataFile.setId(file_id);
		
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(meterFile));
			String meterRecord="";
			while((meterRecord=br.readLine())!=null){
				if(StringUtils.isNotBlank(meterRecord)&&StringUtils.isNotEmpty(meterRecord)){
					meterData = new AssignMeterData(meterRecord);
					assignMeterDataDao.insertEntity(meterData);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}		
		
		dataFile.setRecord_num(record_num);
		dataFile.setSuccess_num(success_num);
		
		if(record_num==0){
			dataFile.setUpload_per(0f);
		}else{
			dataFile.setUpload_per((float)success_num/(float)record_num);
		}
		assignDataFileDao.updateEntity(dataFile);
		
		return dataFile.createUploadEvent();
	}

	//扫描配置文件，获取存储路径和日志文件路径
	/**
	 * D:\tdate
	 */
	private void initCfgFile(){
		this.fileDir="D:"+File.separatorChar+"tdate";
		this.successFileDir = "D:"+File.separatorChar+"tdate"+File.separatorChar+"s_h_data";
		this.failFielDir = "D:"+File.separatorChar+"tdate"+File.separatorChar+"f_h_data";
	}
	
	public static void main(String[] args){
		File f = new File("D:\\tdate\\2012-08-09_13-38-35_102030405060_G.txt");
		System.out.println(f.getName());
		f.delete();
	}

	public String getFileDir() {
		return fileDir;
	}

	public void setFileDir(String fileDir) {
		this.fileDir = fileDir;
	}

	public String getLogfileDir() {
		return logfileDir;
	}

	public void setLogfileDir(String logfileDir) {
		this.logfileDir = logfileDir;
	}

	public AssignMeterDataDao getAssignMeterDataDao() {
		return assignMeterDataDao;
	}

	public void setAssignMeterDataDao(AssignMeterDataDao assignMeterDataDao) {
		this.assignMeterDataDao = assignMeterDataDao;
	}

	public AssignDataFileDao getAssignDataFileDao() {
		return assignDataFileDao;
	}

	public void setAssignDataFileDao(AssignDataFileDao assignDataFileDao) {
		this.assignDataFileDao = assignDataFileDao;
	}

	public String getSuccessFileDir() {
		return successFileDir;
	}

	public void setSuccessFileDir(String successFileDir) {
		this.successFileDir = successFileDir;
	}

	public String getFailFielDir() {
		return failFielDir;
	}

	public void setFailFielDir(String failFielDir) {
		this.failFielDir = failFielDir;
	}
}
